﻿using RQX.Common.Web.Core.AutoMapper;
using RQX.Common.Web.Core.Dto;
using RQX.Common.Web.Core.Entity;
using RQX.Common.Web.Core.Pagger;
using RQX.Common.Web.Core.Repository.DbContext;
using RQX.Common.Web.Web.DynamicApi;
using RQX.Common.Web.Web.Service.Interface;
using System;
using System.Collections.Generic;
using System.Linq;

namespace RQX.Common.Web.Web.Service
{
    [IgnoreApiService]
    public class BaseDtoService<TEntity, TDto, TPagger> : BaseEntityService<TEntity, TPagger>, IDtoService<TEntity, TDto, TPagger>
        where TEntity : BaseEntity
        where TDto : BaseDto
        where TPagger : IPagger
    {
        #region Init
        public BaseDtoService(BaseDbContext context) : base(context) { }
        #endregion

        #region Add
        /// <summary>
        /// 添加单个Dto
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public virtual TDto Add(TDto dto)
        {
            var entity = dto.MapTo<TEntity>();
            var backEntity = AddEntity(entity);
            var backDto = backEntity.MapTo<TDto>();
            return backDto;
        }
        /// <summary>
        /// 添加多个Dto
        /// </summary>
        /// <param name="dtos"></param>
        /// <returns></returns>
        public virtual IEnumerable<TDto> AddList(IEnumerable<TDto> dtos)
        {
            var entities = dtos.MapToList<TEntity>();
            var backEntities = AddEntity(entities);
            var backDtos = backEntities.MapToList<TDto>();
            return backDtos;
        }
        #endregion

        #region Update
        /// <summary>
        /// 更新单个Dto
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public virtual TDto Update(TDto dto)
        {
            var entity = dto.MapTo<TEntity>();
            var backEntity = UpdateEntity(entity);
            var backDto = backEntity.MapTo<TDto>();
            return backDto;
        }
        /// <summary>
        /// 带Entity过滤条件的更新单个Dto
        /// </summary>
        /// <param name="func"></param>
        /// <param name="dto"></param>
        /// <returns></returns>
        public virtual TDto Update(Func<IQueryable<TEntity>, IQueryable<TEntity>> func, TDto dto)
        {
            List<TDto> dtos = new List<TDto>
            {
                dto
            };
            return UpdateList(func, dtos).FirstOrDefault();
        }
        /// <summary>
        /// 更新多个Dto
        /// </summary>
        /// <param name="dtos"></param>
        /// <returns></returns>
        public virtual IEnumerable<TDto> UpdateList(IEnumerable<TDto> dtos)
        {
            var entities = dtos.MapToList<TEntity>();
            var backEntities = UpdateEntity(entities);
            var backDtos = backEntities.MapToList<TDto>();
            return backDtos;
        }
        /// <summary>
        /// 带Entity过滤条件的更新多个Dto
        /// </summary>
        /// <param name="func"></param>
        /// <param name="dtos"></param>
        /// <returns></returns>
        public virtual IEnumerable<TDto> UpdateList(Func<IQueryable<TEntity>, IQueryable<TEntity>> func, IEnumerable<TDto> dtos)
        {
            var entities = dtos.MapToList<TEntity>();
            var updateEntities = DoFilter(entities, func);
            var backEntities = UpdateEntity(updateEntities);
            var backDtos = backEntities.MapToList<TDto>();
            return backDtos;
        }
        #endregion

        #region Remove
        /// <summary>
        /// 通过ID删除
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        public virtual TDto Remove(int primaryKey)
        {
            var entity = Find(primaryKey).FirstOrDefault();
            var result = RemoveEntity(entity);
            return result.MapTo<TDto>();
        }
        /// <summary>
        /// 通过ID列表删除
        /// </summary>
        /// <param name="primaryKeys"></param>
        /// <returns></returns>
        public virtual IEnumerable<TDto> RemoveList(params int[] primaryKeys)
        {
            var entities = Find(primaryKeys);
            var result = RemoveEntity(entities);
            return result.MapToList<TDto>();
        }
        /// <summary>
        /// 带Entity过滤条件的，通过ID列表删除
        /// </summary>
        /// <param name="func"></param>
        /// <param name="primaryKeys"></param>
        /// <returns></returns>
        public virtual IEnumerable<TDto> Remove(Func<IQueryable<TEntity>, IQueryable<TEntity>> func, params int[] primaryKeys)
        {
            var entities = Find(primaryKeys);
            var removeEntities = DoFilter(entities, func);
            var backEntities = RemoveEntity(removeEntities);
            var backDtos = backEntities.MapToList<TDto>();
            return backDtos;
        }
        #endregion

        #region Get
        /// <summary>
        /// 通过ID获取详情Dto
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        public virtual TDto GetInfo(int primaryKey)
        {
            var entity = GetEntityInfo(primaryKey);
            var dto = entity.MapTo<TDto>();
            return dto;
        }
        /// <summary>
        /// 通过ID列表获取详情列表Dtos
        /// </summary>
        /// <param name="primaryKeys"></param>
        /// <returns></returns>
        public virtual IEnumerable<TDto> GetInfoList(params int[] primaryKeys)
        {
            var entities = GetEntityInfo(primaryKeys);
            var dtos = entities.MapToList<TDto>();
            return dtos;
        }
        /// <summary>
        /// 获取全部数据
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<TDto> GetAll()
        {
            var entities = GetAllEntities();
            var dtos = entities.MapToList<TDto>();
            return dtos;
        }
        /// <summary>
        /// 获取全部数据
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<TDto> GetAll(Func<IQueryable<TEntity>, IQueryable<TEntity>> func)
        {
            var entities = GetAllEntities(func);
            var dtos = entities.MapToList<TDto>();
            return dtos;
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pagger"></param>
        /// <returns></returns>
        public virtual BasePaggerBack GetList(TPagger pagger)
        {
            var entities = GetEntityList(pagger, out int rowCount);
            var dtos = entities.MapToList<TDto>();
            return new BasePaggerBack(rowCount, dtos);
        }
        /// <summary>
        /// 带条件的获取分页数据
        /// </summary>
        /// <param name="func"></param>
        /// <param name="pagger"></param>
        /// <returns></returns>
        public virtual BasePaggerBack GetList(Func<IQueryable<TEntity>, IQueryable<TEntity>> func, TPagger pagger)
        {
            var entities = GetEntityList(func, pagger, out int rowCount);
            var dtos = entities.MapToList<TDto>();
            return new BasePaggerBack(rowCount, dtos);
        }
        #endregion
    }
}
